package com.ssy.lingxi.member.merchant.serviceimpl.web;

import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.AuthBO;
import com.ssy.lingxi.member.merchant.model.bo.ButtonBO;
import com.ssy.lingxi.member.merchant.model.constant.MemberUserAuthTypeEnum;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.AuthTreeButtonVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.AuthTreeMenuButtonCheckIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.AuthTreeMenuVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.PlatformMemberDetailQueryButtonVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.RoleUpdateButtonVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.RoleUpdateVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.MemberValidateVO;
import com.ssy.lingxi.member.merchant.repository.MemberRelationAuthRepository;
import com.ssy.lingxi.member.merchant.repository.MemberRelationRepository;
import com.ssy.lingxi.member.merchant.service.base.IBaseAuthService;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberCacheService;
import com.ssy.lingxi.member.merchant.service.web.IPlatformMemberDetailAuthService;
import com.ssy.lingxi.member.merchant.utils.AuthBOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 平台后台 - 会员维护 - 会员详情 - 权限信息服务接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2020-07-16
 */
@Service
public class PlatformMemberDetailAuthServiceImpl implements IPlatformMemberDetailAuthService {
    @Resource
    private MemberRelationAuthRepository relationAuthRepository;

    @Resource
    private IBaseMemberCacheService memberCacheService;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private IBaseAuthService baseAuthService;

    /**
     * 查询会员详情 - 会员权限信息 - 获取会员菜单权限
     * @param headers HttpHeaders信息
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<AuthTreeMenuVO>> getMemberDetailAuthMenu(HttpHeaders headers, MemberValidateVO validateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        List<AuthBO> authBOList = relationDO.getSubRole().getRoleAuth().getAuth();

        return Wrapper.success(AuthBOUtils.transferToTree(authBOList));
    }

    /**
     * 查询会员详情 - 会员权限信息 - 获取会员菜单关联的按钮列表
     *
     * @param queryButtonVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<AuthTreeButtonVO>> getMemberDetailAuthButton(HttpHeaders headers, PlatformMemberDetailQueryButtonVO queryButtonVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(queryButtonVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(queryButtonVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        List<AuthBO> authBOList = relationDO.getSubRole().getRoleAuth().getAuth();

        AuthBO authBO = authBOList.stream().filter(a -> a.getId().equals(queryButtonVO.getMenuId())).findFirst().orElse(null);
        if(authBO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_AUTH_DOES_NOT_EXIST);
        }

        List<AuthTreeButtonVO> buttonVOList = CollectionUtils.isEmpty(authBO.getButtons()) ? new ArrayList<>() : authBO.getButtons().stream().map(button -> new AuthTreeButtonVO(button.getButtonId(), button.getTitle())).collect(Collectors.toList());

        return Wrapper.success(buttonVOList);
    }

    /**
     * 查询左侧树形权限菜单中勾选的Id列表
     *
     * @param headers    HttpHeaders信息
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<AuthTreeMenuButtonCheckIdVO> getTreeCheckIds(HttpHeaders headers, MemberValidateVO validateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        List<AuthBO> authBOList = relationDO.getRelationAuth().getAuth();
        List<Long> checkIds = authBOList.stream().map(AuthBO::getId).collect(Collectors.toList());
        AuthTreeMenuButtonCheckIdVO checkIdVO = new AuthTreeMenuButtonCheckIdVO();
        checkIdVO.setCheckIds(checkIds);
        return Wrapper.success(checkIdVO);
    }

    /**
     * 根据左侧勾选的菜单，查询右侧勾选的按钮Id列表
     *
     * @param headers       HttpHeaders信息
     * @param queryButtonVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<AuthTreeMenuButtonCheckIdVO> getButtonCheckIds(HttpHeaders headers, PlatformMemberDetailQueryButtonVO queryButtonVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(queryButtonVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(queryButtonVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        List<AuthBO> authBOList = relationDO.getRelationAuth().getAuth();
        AuthBO authBO = authBOList.stream().filter(auth -> auth.getId().equals(queryButtonVO.getMenuId())).findFirst().orElse(null);

        AuthTreeMenuButtonCheckIdVO checkIdVO = new AuthTreeMenuButtonCheckIdVO();
        if(authBO == null) {
            checkIdVO.setCheckIds(new ArrayList<>());
        } else {
            checkIdVO.setCheckIds(authBO.getButtons().stream().map(ButtonBO::getButtonId).collect(Collectors.toList()));
        }

        return Wrapper.success(checkIdVO);
    }

    /**
     * 更新左侧菜单权限
     *
     * @param headers Http头部信息
     * @param updateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateMemberRole(HttpHeaders headers, RoleUpdateVO updateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(updateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(updateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MemberRelationAuthDO relationAuthDO = relationDO.getRelationAuth();
        if(relationAuthDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_AUTH_DOES_NOT_EXIST);
        }

        List<AuthBO> authBOList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(updateVO.getMenuIds())) {
            if(!updateVO.getMenuIds().stream().allMatch(menuId -> relationDO.getSubRole().getRoleAuth().getAuth().stream().anyMatch(authBO -> authBO.getId().equals(menuId)))) {
                return Wrapper.fail(ResponseCode.MC_MS_MEMBER_AUTH_DOES_NOT_EXIST);
            }

            authBOList = relationDO.getSubRole().getRoleAuth().getAuth().stream().filter(authBO -> updateVO.getMenuIds().contains(authBO.getId())).collect(Collectors.toList());
        }

        if(AuthBOUtils.listNotEqual(relationAuthDO.getAuth(), authBOList)) {
            relationAuthDO.setAuth(authBOList);
            relationAuthRepository.saveAndFlush(relationAuthDO);

            //合并会员、下属角色、下属用户的权限
            return baseAuthService.mergeMemberAuthFromRelation(relationDO.getSubMember());
        }

        return Wrapper.success();
    }

    /**
     * 更新权限菜单关联按钮
     *
     * @param headers        HttpHeaders信息
     * @param updateButtonVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateMemberRoleButton(HttpHeaders headers, RoleUpdateButtonVO updateButtonVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(updateButtonVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(updateButtonVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MemberRelationAuthDO relationAuthDO = relationDO.getRelationAuth();
        if(relationAuthDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_AUTH_DOES_NOT_EXIST);
        }

        RoleDO roleDO = relationDO.getSubRole();
        if(roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        List<AuthBO> roleAuthBOList = roleDO.getRoleAuth().getAuth();
        if(roleAuthBOList.stream().noneMatch(roleAuth -> roleAuth.getId().equals(updateButtonVO.getMenuId()))) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_AUTH_DOES_NOT_EXIST);
        }

        //会员下属管理员
        MemberRoleDO memberAdminRoleDO = relationDO.getSubMember().getMemberRoles().stream().filter(memberRoleDO -> memberRoleDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
        if(memberAdminRoleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_ROLE_DOES_NOT_EXIST);
        }

        //会员下属管理员用户
        MemberUserDO memberAdminUser = relationDO.getSubMember().getUsers().stream().filter(memberUserDO -> memberUserDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
        if(memberAdminUser == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        //这里要复制一份，否则会改变角色的权限
        AuthBO roleAuthBo = roleAuthBOList.stream().filter(roleAuth -> roleAuth.getId().equals(updateButtonVO.getMenuId())).findFirst().orElse(null);
        if(roleAuthBo == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_AUTH_DOES_NOT_EXIST);
        }

        AuthBO newAuthBO = AuthBOUtils.copy(roleAuthBo);
        if(CollectionUtils.isEmpty(updateButtonVO.getButtonIds())) {
            newAuthBO.getButtons().clear();
        } else {
            if(!updateButtonVO.getButtonIds().stream().allMatch(buttonId -> newAuthBO.getButtons().stream().anyMatch(b -> b.getButtonId().equals(buttonId)))) {
                return Wrapper.fail(ResponseCode.MC_MS_BUTTON_DOES_NOT_EXIST);
            }

            newAuthBO.getButtons().removeIf(button -> !updateButtonVO.getButtonIds().contains(button.getButtonId()));
        }

        List<AuthBO> memberAuthBOList = relationDO.getRelationAuth().getAuth();
        memberAuthBOList.removeIf(memberAuth -> memberAuth.getId().equals(newAuthBO.getId()));
        memberAuthBOList.add(newAuthBO);

        relationAuthDO.setAuth(memberAuthBOList);
        relationAuthRepository.saveAndFlush(relationAuthDO);

        //合并会员、下属角色、下属用户的权限
        return baseAuthService.mergeMemberAuthFromRelation(relationDO.getSubMember());
    }
}
